#include<iostream>
#include<deque>
#include<cstring>
#include <climits>

using namespace std;
const int N=1e3+10;
typedef pair<int,int> PII;
char numset[N][N];
int dist1[N][N];
int dist2[N][N];
int dist3[N][N];
int n,m;

int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};

void bfs(int dist[][N],char flag)
{

	deque<PII> dq;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			dist[i][j]=-1;
			if(numset[i][j]==flag)
			{
				dq.push_front({i,j});
				dist[i][j]=0;
			}
		}
	}

	while(!dq.empty())
	{
		int x=dq.front().first;
		int y=dq.front().second;

		dq.pop_front();

		for(int i=0;i<4;i++)
		{
			int newx=x+dx[i];
			int newy=y+dy[i];

			if(newx<=n&&newy<=m&&newy>=1&&newx>=1
				&&numset[newx][newy]!='#')
			{
				int w=(numset[newx][newy]=='.'?1:0);
				if(dist[newx][newy]==-1||dist[x][y]+w<dist[newx][newy])
				{
					
					if(numset[newx][newy]=='.')
					{
						dq.push_back({newx,newy});
					}
					else
					{
						dq.push_front({newx,newy});
					}
					dist[newx][newy]=dist[x][y]+w;
				}
			}
		}
	}
}

int main()
{
	cin>>n>>m;

	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>numset[i][j];
		}
	}

	bfs(dist1,'1');
	bfs(dist2,'2');
	bfs(dist3,'3');

	int ret=INT_MAX;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(dist1[i][j]==-1||dist2[i][j]==-1||dist3[i][j]==-1) continue;
			if(numset[i][j]=='.')
			{
				if(dist1[i][j]!=-1 && dist2[i][j]!=-1 && dist3[i][j]!=-1)
				ret=min(ret,dist1[i][j]+dist2[i][j]+dist3[i][j]-2);
			}
			else 
			{
				ret=min(ret,dist1[i][j]+dist2[i][j]+dist3[i][j]);
			}
		}
	}
	if(ret == INT_MAX) cout << -1 << "\n";
	else cout << ret << "\n";
}